<?php
declare(strict_types=1);
namespace app\core;


class RelationModel
{
    private $_relation=[];
    public function __construct()
    {
        $this->init();
    }

    // 初始化
    protected function init()
    {}

    public function from($mainName,$field='',$map=[]){
        $this->_relation['from']=[
            'table'=>$mainName,
            'field'=>$field,
            'map'=>$map
        ];
        return $this;
    }

    public function join($table,$on,$type='join',$field='',$map=[]){
        $tmp=[
            'table'=>$table,
            'on'=>$on,
            'type'=>$type,
            'field'=>$field,
            'map'=>$map
        ];
        $this->_relation['join'][]=$tmp;
        return $this;
    }

    public function mField($field='*'){
        $this->_relation['field']=$field;
        return $this;
    }

    public function mMap($map=[]){
        $this->_relation['map']=$map;
        return $this;
    }

    public function getModel(){
        $model=NULL;
        $from=Res::kv($this->_relation,'from');
        $mTable=Res::kv($from,'table');
        if($mTable!=''){
            $tableAlias=$this->tableAlias();
            $model=Relation::getModel($mTable)->alias(Res::kv($tableAlias,$mTable));
            $mField=Res::kv($from,'field');
            if($mField!=''){
                $flist=explode(',',$mField);
                $ftmp=[];
                foreach($flist as $k=>$fit){
                    $ftmp[]=Res::kv($tableAlias,$mTable).'.'.$fit;
                }
                $cfield=implode(',',$ftmp);
                $model->field($cfield);
            }

            $mMap=Res::kv($from,'map');
            if($mMap!=''){
                $cMap=[];
                foreach($mMap as $k=>$mapit){
                    $cMap[]=[Res::kv($tableAlias,$mTable).'.'.$mapit[0],$mapit[1],$mapit[2]];
                }
                $model->where($cMap);
            }

            $joinList=Res::kv($this->_relation,'join');
            if($joinList!=''){
                foreach($joinList as $items){
                    $name=$items['table']." ".Res::kv($tableAlias,$items['table']);
                    
                    $model=$this->swithjoin($model,$name,$items['on'],$items['type']);
                    $field=Res::kv($items,'field');
                    if($field!=''){
                        $flist=explode(',',$field);
                        $ftmp=[];
                        foreach($flist as $k=>$fit){
                            $ftmp[]=Res::kv($tableAlias,$items['table']).'.'.$fit;
                        }
                        $cfield=implode(',',$ftmp);
                        $model->field($cfield);
                    }
                    $map=Res::kv($items,'map');
                    if($map!=''){
                        $cMap=[];
                        foreach($map as $k=>$mapit){
                            $cMap[]=[Res::kv($tableAlias,$items['table']).'.'.$mapit[0],$mapit[1],$mapit[2]];
                        }
                        $model->where($cMap);
                    }
                }
            }
        }
        return $model;
    }

    protected function tableAlias(){
        $res=[];
        $from=Res::kv($this->_relation,'from');
        $mTable=Res::kv($from,'table');
        if($mTable!=''){
            $res[$mTable]='m';
            $joinList=Res::kv($this->_relation,'join');
            if($joinList!=''){
                foreach($joinList as $k=>$items){
                    $res[$items['table']]='j'.$k;
                }
            }

            $jTmp=json_encode($this->_relation);
            foreach($res as $key=>$value){
                $jTmp=str_replace($key.'.',$value.'.',$jTmp);
            }
            $this->_relation=json_decode($jTmp,true);
        }
        return $res;
    }

    protected function swithjoin($model,$table,$on,$join='join'){
        if($join=='leftJoin'){
            return $model->leftJoin($table,$on);

        }else if($join=='rightJoin'){
            return $model->rightJoin($table,$on);

        }else if($join=='fullJoin'){
            return $model->fullJoin($table,$on);
        }else{
            return $model->join($table,$on);
        }
    }


}
